package com.pyb.common.upload.utils;

import com.google.common.base.Preconditions;

import org.apache.commons.lang3.tuple.ImmutablePair;

import java.awt.geom.AffineTransform;
import java.awt.image.AffineTransformOp;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;

import javax.imageio.ImageIO;


/**
 * ImageUtil
 *
 * @author chuchen.zhang
 * @date 17-2-19 下午10:00
 */
public class ImageUtil {

	public static byte[] resizeImg(InputStream originImg, Integer resizeWidth, Integer resizeHeight
			, boolean isConstrain) {
		checkArgument(originImg, resizeWidth, resizeHeight, isConstrain);
		byte[] resizedImg = null;
		try {
			AffineTransform transform = new AffineTransform();
			//读取图片
			BufferedImage bis = ImageIO.read(originImg);
			//获得图片原来的高宽
			int w = bis.getWidth();
			int h = bis.getHeight();

			ImmutablePair<Double, Double> scalePair = caculateScale(resizeWidth, resizeHeight, w, h, isConstrain);

			transform.setToScale(scalePair.getKey(), scalePair.getValue());

			AffineTransformOp ato = new AffineTransformOp(transform, null);
			BufferedImage bid = new BufferedImage(resizeWidth, resizeHeight,
					BufferedImage.TYPE_3BYTE_BGR);
			ato.filter(bis, bid);
			ByteArrayOutputStream out = new ByteArrayOutputStream();

			ImageIO.write(bid, "png", out);
			resizedImg = out.toByteArray();
		} catch (Exception e) {
			e.printStackTrace();
		}
		return resizedImg;
	}

	private static void checkArgument(InputStream originImg, Integer resizeWidth, Integer resizeHeight
			, boolean isConstrain) {
		Preconditions.checkNotNull(originImg, "origin image is empty!");
		resizeWidth = resizeWidth != null ? resizeWidth : 0;
		resizeHeight = resizeHeight != null ? resizeHeight : 0;
		if (isConstrain) {
			Preconditions.checkArgument(
					(resizeHeight > 0) || (resizeWidth > 0)
					, "size after resizeed are both empty or less than zero"
			);
		} else {
			Preconditions.checkArgument(
					(resizeHeight > 0) && (resizeWidth > 0)
					, "one of size after resizeed is empty or less than zero"
			);
		}
	}

	private static ImmutablePair<Double, Double> caculateScale(int resizeWidth, int resizeHeight
			, int originWidth, int originHeight, boolean isConstrain) {
		if (isConstrain) {
			boolean isDependOnresizeWidth
					= isScaleDependOnWidth(resizeWidth, resizeHeight, originWidth, originHeight);
			double scale;
			if (isDependOnresizeWidth) {
				scale = (double) resizeWidth / originWidth;
			} else {
				scale = (double) resizeHeight / originHeight;
			}
			return new ImmutablePair<Double, Double>(scale, scale);
		}
		return new ImmutablePair<Double, Double>(
				(double) resizeWidth / originWidth, (double) resizeHeight / originHeight
		);
	}

	private static boolean isScaleDependOnWidth(int resizeWidth, int resizeHeight
			, int originWidth, int originHeight) {
		if (resizeHeight <= 0) {
			return true;
		}
		if (resizeWidth <= 0) {
			return false;
		}
		return ((double) resizeWidth / originWidth) < ((double) resizeHeight / originHeight);
	}
}
